const fs_extra = require('fs-extra');
const fs_plus = require('fs-plus');
const node_downloader_helper = require('node-downloader-helper');
const path = require('path');
const ProgressBar = require('progress');


const download = (url, downloadDir, options = {}) => {
    return new Promise((resolve, reject) => {
        const DEFAULT_OPTIONS = {
            progress: null,
            end: null,
            error: null
        }
        if (typeof options !== 'object')
            options = DEFAULT_OPTIONS;
        else
            options = { ...DEFAULT_OPTIONS, ...options };
        try {
            fs_extra.ensureDirSync(downloadDir);
            const fileName = path.basename(url);
            const filePath = path.join(downloadDir, './' + fileName);
            if (fs_plus.isFileSync(filePath))
                fs_extra.removeSync(filePath);
        } catch (error) {
            resolve([error, url]);
            return;
        }
        const { DownloaderHelper } = node_downloader_helper;
        const dl = new DownloaderHelper(url, downloadDir, {
            override: true,
            timeout: 15000,
            retry: false
        });
        // const bar = new ProgressBar('  downloading [:bar] :rate/bps :percent :etas', {
        //     complete: '=',
        //     incomplete: ' ',
        //     width: 20,
        //     total: 100
        // });
        dl.on('progress', (stats) => {
            // stats.progress && bar.tick(stats.progress * 100);
            if (typeof options.progress === 'function') {
                options.progress(stats);
            }
        });
        dl.on('end', (downloadInfo) => {
            if (typeof options.end === 'function') {
                options.end(downloadInfo);
            }
            resolve([null, downloadInfo.filePath]);
        });
        dl.on('error', (error) => {
            console.log('Download Failed', error);
            if (typeof options.error === 'function') {
                options.error(error);
            }
            resolve([error, url]);
        });
        dl.on('timeout', () => {
            console.log('Download Timeout');
            if (typeof options.timeout === 'function') {
                options.timeout('Download Timeout');
            }
            resolve(['Download Timeout', url]);
        });
        dl.start().catch((error) => {
            console.log('Download Failed', error);
            if (typeof options.error === 'function') {
                options.error(error);
            }
            resolve([error, url]);
        });
    });
}

const downloadPackage = async (packageInfo, version) => {
    const package = packageInfo.packages[0];
    const { platforms, tools } = package;
    for (let item of platforms) {
        if (version !== item.version) {
            continue;
        }
        let targetPath = item.url.replace('https://', `arduino-packages/${package.name}/`);
        if (!fs_plus.isFileSync(targetPath)) {
            console.log(`开始下载${item.url}`);
            try {
                await download(item.url, path.dirname(targetPath));
                console.log(`${item.url}下载成功`);
            } catch (error) {
                console.log(`${item.url}下载失败`, error);
            }
        }

        for (let toolsDependency of item.toolsDependencies) {
            for (let tool of tools) {
                if (toolsDependency.name !== tool.name || toolsDependency.version !== tool.version) {
                    continue;
                }
                for (let childen of tool.systems) {
                    let targetPath = childen.url.replace('https://', `arduino-packages/${package.name}/`);
                    if (fs_plus.isFileSync(targetPath)) {
                        continue;
                    }
                    console.log(`开始下载${childen.url}`);
                    try {
                        await download(childen.url, path.dirname(targetPath));
                        console.log(`${childen.url}下载成功`);
                    } catch (error) {
                        console.log(`${childen.url}下载失败`, error);
                    }
                }
            }
        }
    }
}

const info = fs_extra.readJSONSync('./packages/package_esp32_index.json');

downloadPackage(info, '2.0.6')
    .then(() => {
        console.log('全部下载完成');
    })
    .catch((error) => {
        console.log('下载失败', error);
    });